package com.kede.api.auth.service.impl;

import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.kede.api.auth.domain.LoginUser;
import com.kede.api.auth.domain.User;
import com.kede.api.auth.domain.WeixTokenDomain;
import com.kede.api.auth.service.LoginService;
import com.kede.api.auth.service.WeixTokenService;
import com.kede.api.bean.RedisBean;
import com.kede.api.ienum.AppIdTypeEnum;
import com.kede.pojo.ResHttp;
import com.kede.utils.JwtUtil;
import lombok.Data;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.time.temporal.TemporalUnit;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

/***
 ** @Author:Pr.li
 ** @Description:
 ** @Date: create in 2023/3/31 15:26
 ***/
@Service
public class LoginServiceImpl implements LoginService {

    @Resource
    private AuthenticationManager authenticationManager;

    @Resource
    private RedisBean redisBean;

    @Resource
    private WeixTokenService weixTokenService;


    @Override
    public ResHttp login(User user) {
//        AuthenticationManager authenticationManager 进行认证
        UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(user.getUserName(),user.getPassword());
        Authentication authenticate = authenticationManager.authenticate(authenticationToken);
        if (Objects.isNull(authenticate)) {
            throw new RuntimeException("登录失败");
        }
        LoginUser loginUser = (LoginUser) authenticate.getPrincipal();
        String id = loginUser.getUser().getId().toString();
        String jwt = JwtUtil.createJWT(id);
        HashMap<Object, Object> m = new HashMap<>();
        m.put("token",jwt);

        redisBean.setCacheObject("login:"+id,loginUser,1, TimeUnit.HOURS);
        return ResHttp.okData(m);
    }

    @Override
    public ResHttp logout() {
        //获取SecurityContextHolder中的用户id
        UsernamePasswordAuthenticationToken authentication = (UsernamePasswordAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
        LoginUser loginUser = (LoginUser) authentication.getPrincipal();
        Long id = loginUser.getUser().getId();

        redisBean.deleteObject("login:"+id);
        return ResHttp.ok("注销成功");
    }

    @Override
    public void loginByPhone(String phone, AppIdTypeEnum appIdTypeEnum) {

        switch (appIdTypeEnum){
            case USER_XCX:

                break;
        }
    }


    public String getToken(AppIdTypeEnum appIdTypeEnum){
        LambdaQueryWrapper<WeixTokenDomain> queryWrapper = new LambdaQueryWrapper<>();
        LocalDateTime now = LocalDateTime.now();
        queryWrapper.eq(WeixTokenDomain::getType,appIdTypeEnum.getType());
        WeixTokenDomain one = weixTokenService.getOne(queryWrapper);

        if (one == null){
            //更新token；
            TokenEntity tokenEntity = doGetToken(appIdTypeEnum);
            WeixTokenDomain weixTokenDomain = new WeixTokenDomain();
            weixTokenDomain.setToken(tokenEntity.getAccess_token());
            weixTokenDomain.setCreateTime(now);
            weixTokenDomain.setUpdateTime(now);
            weixTokenDomain.setType(appIdTypeEnum.getType());
            weixTokenDomain.setTime(tokenEntity.getTime());
            weixTokenService.save(weixTokenDomain);
            return tokenEntity.getAccess_token();
        }else if(one.getTime().isBefore(now)){
//            过期了
            TokenEntity tokenEntity = doGetToken(appIdTypeEnum);
            one.setToken(tokenEntity.getAccess_token());
            one.setTime(tokenEntity.getTime());
            one.setUpdateTime(now);
            weixTokenService.updateById(one);
            return tokenEntity.getAccess_token();
        }else {
            return one.getToken();
        }
    }

    public TokenEntity doGetToken(AppIdTypeEnum appIdTypeEnum){
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential");
        stringBuilder.append("&appid=");
        stringBuilder.append(appIdTypeEnum.getAppid());
        stringBuilder.append("&secret=");
        stringBuilder.append(appIdTypeEnum.getAppSecret());
        String s = HttpUtil.get(stringBuilder.toString());
        LocalDateTime end = LocalDateTime.now();
        end.plusSeconds(7000);
        TokenEntity tokenEntity = JSONObject.parseObject(s, TokenEntity.class);
        tokenEntity.setTime(end);
        return tokenEntity;
    }

    /**
     * {
     *     "errcode":0,
     *     "errmsg":"ok",
     *     "phone_info": {
     *         "phoneNumber":"xxxxxx",
     *         "purePhoneNumber": "xxxxxx",
     *         "countryCode": 86,
     *         "watermark": {
     *             "timestamp": 1637744274,
     *             "appid": "xxxx"
     *         }
     *     }
     * }
     * @param code
     * @param appIdTypeEnum
     * @return
     */
    @Override
    public String getWxPhone(String code,AppIdTypeEnum appIdTypeEnum){
        String url ="https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token="+this.getToken(appIdTypeEnum);
        Map<String,Object> map = new HashMap<>();
        map.put("code",code);
        String post = HttpUtil.post(url, map);
        return post;
    }

    @Data
    private class TokenEntity{
        private String access_token;
        private Integer expires_in;
        private LocalDateTime time;
    }

}
